package com.me.batm;

import java.util.ArrayList;

import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.me.batm.models.GameEntity;
import com.me.batm.models.Person;

public class Utils  {

	public static float EPS = 2f;
	
	public static float tileWidth,tileHeight;
	public static int layerWidth,layerHeight;
	
	public static Vector2 getTilePositionToXY(int x,int y){
		Vector2 pos = new Vector2();
		
		pos.x = x * tileWidth + tileWidth / 2f;
		pos.y = layerHeight * tileHeight - (y * tileHeight + tileHeight / 2f);		
		return pos;
	}
	
	public static Vector2 getXYToTilePosition(float x,float y){
		Vector2 pos = new Vector2();
		
		pos.x = x / tileWidth;
		pos.y = layerHeight - (y / tileHeight);
		
		return pos;
	}
	
	// using booleans
	public static boolean somethingUp(Person person, Boolean[][] map) {		
		int colMin = (int)person.getX(),
				colMax = (int)person.getX() + (int) person.getWidth(),
				i = (int) person.getY() + (int)person.getHeight() - map.length;
		for (int j = colMin; j <= colMax; j += 1) {
			if (map[i - 1][j]) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean somethingDown(Person person, Boolean[][] map) {
		int colMin = (int)person.getX(),
				colMax = (int)person.getX() + (int) person.getWidth(),
				i = (int) person.getY() - map.length;
		for (int j = colMin; j <= colMax; j += 1) {
			if (map[i + 1][j]) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean somethingLeft(Person person, Boolean[][] map) {
		int rowMin = (int)person.getY() + (int) person.getHeight(),
				rowMax = (int)person.getY(),
				j = (int) person.getX();
		for (int i = rowMin; i <= rowMax; i += 1) {
			if (map[i][j - 1]) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean somethingRight(Person person, Boolean[][] map) {
		int rowMin = (int)person.getY() + (int) person.getHeight(),
				rowMax = (int)person.getY(),
				j = (int) person.getX() + (int) person.getWidth();
		for (int i = rowMin; i <= rowMax; i += 1) {
			if (map[i][j + 1]) {
				return true;
			}
		}
		return false;
	}
	
	// using an arraylist of polygons
	public static boolean somethingUp(Person person, ArrayList<GameEntity> obstacles) {		
		for (int i = 0; i < obstacles.size(); ++i) {
			Rectangle p = person.shape;
			Rectangle o = obstacles.get(i).shape;
			if (o.getY() > p.getY() + p.getHeight() && 	// obstacle is on top of the person
					Math.abs(o.getY() - (p.getY() + p.getHeight())) <= EPS && // there's a distance between them less than EPS
					// projection of two segments
					p.getX() + p.getWidth() > o.getX() && 
					o.getX() + o.getWidth() > p.getX()					
					) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean somethingDown(Person person, ArrayList<GameEntity> obstacles) {		
		for (int i = 0; i < obstacles.size(); ++i) {
			Rectangle p = person.shape;
			Rectangle o = obstacles.get(i).shape;
			if (p.getY() > o.getY() + o.getHeight() && 	// person is on top of the obstacle
					Math.abs(p.getY() - (o.getY() + o.getHeight())) <= EPS && // there's a distance between them less than EPS
					// projection of two segments
					p.getX() + p.getWidth() > o.getX() && 
					o.getX() + o.getWidth() > p.getX()					
					) {
				return true;
			}
		}
		return false;
	}
	
	
	
	public static boolean somethingRight(Person person, ArrayList<GameEntity> obstacles) {		
		for (int i = 0; i < obstacles.size(); ++i) {
			Rectangle p = person.shape;
			Rectangle o = obstacles.get(i).shape;
			if (o.getX() > p.getX() + p.getWidth() && 	// obstacle is on the right of the person
					Math.abs(o.getX() - (p.getX() + p.getWidth())) <= EPS && // there's a distance between them less than EPS
					// projection of two segments
					p.getY() + p.getHeight() > o.getY() && 
					o.getY() + o.getHeight() > p.getY()					
					) {
				return true;
			}
		}
		return false;
	}
	
	public static Vector2 rotateAround(Vector2 point,Vector2 center,float angle){
		float x = point.x - center.x;
		float y = point.y - center.y;
		
		angle = (float) (angle * Math.PI / 180f);
		
		float dx = (float) (x * Math.cos(angle) - y * Math.sin(angle));
		float dy = (float) (x * Math.sin(angle) + y * Math.cos(angle));
		
		x = dx + center.x;
		y = dy + center.y;
		return new Vector2(x,y);
	}
	public static boolean somethingLeft(Person person, ArrayList<GameEntity> obstacles) {		
		for (int i = 0; i < obstacles.size(); ++i) {
			Rectangle p = person.shape;
			Rectangle o = obstacles.get(i).shape;
			if (p.getX() > o.getX() + o.getWidth() && 	// obstacle is on the left of the person
					Math.abs(p.getX() - (o.getX() + o.getWidth())) <= EPS && // there's a distance between them less than EPS
					// projection of two segments
					p.getY() + p.getHeight() > o.getY() && 
					o.getY() + o.getHeight() > p.getY()					
					) {
				return true;
			}
		}
		return false;
	}
	
	public static boolean willCrash(Rectangle player, Array<Rectangle> obstacles) {
		int i;
		for (i = 0; i < obstacles.size; i += 1) {
			if (obstacles.get(i).overlaps(player)) {
				return true;
			}
		}
		return false;
	}
	
	public static void swap(int a, int b) {
		int temp = a;
		a = b;
		b = temp;
	}
}
